from examples.example_3_simplest_case_priority_resource.ex_3_model_classes import Trial, g
from vidigi.prep import reshape_for_animations, generate_animation_df
from vidigi.animation import generate_animation
from vidigi.animation import animate_activity_log
import pandas as pd
import plotly.io as pio
pio.renderers.default = "notebook"Example 3: Simplest Case - with a Priority Resource
my_trial = Trial()
my_trial.run_trial()4 nurses
my_trial.all_event_logs.head(50)| patient | pathway | event_type | event | time | resource_id | run | |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | arrival_departure | arrival | 0.000000 | NaN | 0 |
| 1 | 1 | 2 | queue | treatment_wait_begins | 0.000000 | NaN | 0 |
| 2 | 1 | 2 | resource_use | treatment_begins | 0.000000 | 1.0 | 0 |
| 3 | 2 | 2 | arrival_departure | arrival | 3.399660 | NaN | 0 |
| 4 | 2 | 2 | queue | treatment_wait_begins | 3.399660 | NaN | 0 |
| 5 | 2 | 2 | resource_use | treatment_begins | 3.399660 | 2.0 | 0 |
| 6 | 3 | 2 | arrival_departure | arrival | 8.497645 | NaN | 0 |
| 7 | 3 | 2 | queue | treatment_wait_begins | 8.497645 | NaN | 0 |
| 8 | 3 | 2 | resource_use | treatment_begins | 8.497645 | 3.0 | 0 |
| 9 | 4 | 2 | arrival_departure | arrival | 8.596678 | NaN | 0 |
| 10 | 4 | 2 | queue | treatment_wait_begins | 8.596678 | NaN | 0 |
| 11 | 4 | 2 | resource_use | treatment_begins | 8.596678 | 4.0 | 0 |
| 12 | 5 | 2 | arrival_departure | arrival | 8.608025 | NaN | 0 |
| 13 | 5 | 2 | queue | treatment_wait_begins | 8.608025 | NaN | 0 |
| 14 | 6 | 2 | arrival_departure | arrival | 11.359739 | NaN | 0 |
| 15 | 6 | 2 | queue | treatment_wait_begins | 11.359739 | NaN | 0 |
| 16 | 7 | 2 | arrival_departure | arrival | 19.509442 | NaN | 0 |
| 17 | 7 | 2 | queue | treatment_wait_begins | 19.509442 | NaN | 0 |
| 18 | 8 | 2 | arrival_departure | arrival | 22.877356 | NaN | 0 |
| 19 | 8 | 2 | queue | treatment_wait_begins | 22.877356 | NaN | 0 |
| 20 | 9 | 2 | arrival_departure | arrival | 26.653863 | NaN | 0 |
| 21 | 9 | 2 | queue | treatment_wait_begins | 26.653863 | NaN | 0 |
| 22 | 1 | 2 | resource_use_end | treatment_complete | 40.317385 | 1.0 | 0 |
| 23 | 1 | 2 | arrival_departure | depart | 40.317385 | NaN | 0 |
| 24 | 5 | 2 | resource_use | treatment_begins | 40.317385 | 1.0 | 0 |
| 25 | 10 | 2 | arrival_departure | arrival | 40.737793 | NaN | 0 |
| 26 | 10 | 2 | queue | treatment_wait_begins | 40.737793 | NaN | 0 |
| 27 | 2 | 2 | resource_use_end | treatment_complete | 42.443230 | 2.0 | 0 |
| 28 | 2 | 2 | arrival_departure | depart | 42.443230 | NaN | 0 |
| 29 | 6 | 2 | resource_use | treatment_begins | 42.443230 | 2.0 | 0 |
| 30 | 4 | 2 | resource_use_end | treatment_complete | 48.809628 | 4.0 | 0 |
| 31 | 4 | 2 | arrival_departure | depart | 48.809628 | NaN | 0 |
| 32 | 7 | 2 | resource_use | treatment_begins | 48.809628 | 4.0 | 0 |
| 33 | 3 | 2 | resource_use_end | treatment_complete | 51.483457 | 3.0 | 0 |
| 34 | 3 | 2 | arrival_departure | depart | 51.483457 | NaN | 0 |
| 35 | 8 | 2 | resource_use | treatment_begins | 51.483457 | 3.0 | 0 |
| 36 | 11 | 2 | arrival_departure | arrival | 71.026558 | NaN | 0 |
| 37 | 11 | 2 | queue | treatment_wait_begins | 71.026558 | NaN | 0 |
| 38 | 5 | 2 | resource_use_end | treatment_complete | 77.447488 | 1.0 | 0 |
| 39 | 5 | 2 | arrival_departure | depart | 77.447488 | NaN | 0 |
| 40 | 9 | 2 | resource_use | treatment_begins | 77.447488 | 1.0 | 0 |
| 41 | 6 | 2 | resource_use_end | treatment_complete | 83.962251 | 2.0 | 0 |
| 42 | 6 | 2 | arrival_departure | depart | 83.962251 | NaN | 0 |
| 43 | 10 | 2 | resource_use | treatment_begins | 83.962251 | 2.0 | 0 |
| 44 | 12 | 2 | arrival_departure | arrival | 87.458700 | NaN | 0 |
| 45 | 12 | 2 | queue | treatment_wait_begins | 87.458700 | NaN | 0 |
| 46 | 13 | 2 | arrival_departure | arrival | 87.465138 | NaN | 0 |
| 47 | 13 | 2 | queue | treatment_wait_begins | 87.465138 | NaN | 0 |
| 48 | 7 | 2 | resource_use_end | treatment_complete | 95.498040 | 4.0 | 0 |
| 49 | 7 | 2 | arrival_departure | depart | 95.498040 | NaN | 0 |
STEP_SNAPSHOT_MAX = 45
LIMIT_DURATION = g.sim_duration
WRAP_QUEUES_AT = 15full_patient_df = reshape_for_animations(
event_log=my_trial.all_event_logs[my_trial.all_event_logs['run']==1],
every_x_time_units=2,
step_snapshot_max=STEP_SNAPSHOT_MAX,
limit_duration=LIMIT_DURATION,
debug_mode=True
)
full_patient_df.head(15)Iteration through minute-by-minute logs complete 10:21:51
Snapshot df concatenation complete at 10:21:51
| index | patient | pathway | event_type | event | time | resource_id | run | rank | minute | additional | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 0 | NaN |
| 1 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 2 | NaN |
| 2 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 4 | NaN |
| 3 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 6 | NaN |
| 4 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 8 | NaN |
| 5 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 10 | NaN |
| 6 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 12 | NaN |
| 7 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 14 | NaN |
| 8 | 5 | 2 | 2 | resource_use | treatment_begins | 12.021043 | 2.0 | 1 | 2.0 | 14 | NaN |
| 9 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 16 | NaN |
| 10 | 5 | 2 | 2 | resource_use | treatment_begins | 12.021043 | 2.0 | 1 | 2.0 | 16 | NaN |
| 11 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 18 | NaN |
| 12 | 5 | 2 | 2 | resource_use | treatment_begins | 12.021043 | 2.0 | 1 | 2.0 | 18 | NaN |
| 13 | 2 | 1 | 1 | resource_use | treatment_begins | 0.000000 | 1.0 | 1 | 1.0 | 20 | NaN |
| 14 | 5 | 2 | 2 | resource_use | treatment_begins | 12.021043 | 2.0 | 1 | 2.0 | 20 | NaN |
event_position_df = pd.DataFrame([
{'event': 'arrival',
'x': 50, 'y': 300,
'label': "Arrival" },
# Triage - minor and trauma
{'event': 'treatment_wait_begins',
'x': 205, 'y': 275,
'label': "Waiting for Treatment"},
{'event': 'treatment_begins',
'x': 205, 'y': 175,
'resource':'n_cubicles',
'label': "Being Treated"},
{'event': 'exit',
'x': 270, 'y': 70,
'label': "Exit"}
])full_patient_df_plus_pos = generate_animation_df(full_patient_df=full_patient_df,
event_position_df=event_position_df,
wrap_queues_at=WRAP_QUEUES_AT,
step_snapshot_max=STEP_SNAPSHOT_MAX,
gap_between_entities=10,
gap_between_resources=10,
gap_between_rows=30,
debug_mode=True
)
full_patient_df_plus_pos.sort_values(['patient', 'minute']).head(15)Placement dataframe finished construction at 10:21:51
| index | patient | pathway | event_type | event | time | resource_id | run | rank | minute | additional | x | y_final | label | resource | x_final | row | icon | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 10186 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 0 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10187 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 2 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10188 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 4 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10189 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 6 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10190 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 8 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10191 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 10 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10192 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 12 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10193 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 14 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10194 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 16 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10195 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 18 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10196 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 20 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10197 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 22 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10198 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 24 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10199 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 26 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
| 10200 | 2 | 1 | 1 | resource_use | treatment_begins | 0.0 | 1.0 | 1 | 1.0 | 28 | NaN | 205 | 175.0 | Being Treated | n_cubicles | 195.0 | NaN | 🧔🏼 |
def show_priority_icon(row):
if "more" not in row["icon"]:
if row["pathway"] == 1:
return "🚨"
else:
return row["icon"]
else:
return row["icon"]full_patient_df_plus_pos = full_patient_df_plus_pos.assign(
icon=full_patient_df_plus_pos.apply(show_priority_icon, axis=1)
)full_patient_df_plus_pos.head(15)| index | patient | pathway | event_type | event | time | resource_id | run | rank | minute | additional | x | y_final | label | resource | x_final | row | icon | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 155 | 49 | 2 | queue | exit | 206.540636 | NaN | 1 | 3.0 | 600 | NaN | 270 | 70.0 | Exit | NaN | 250.0 | 0.0 | 🧕🏾 |
| 1 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 208 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 2 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 210 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 3 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 212 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 4 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 214 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 5 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 216 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 6 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 218 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 7 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 220 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 8 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 222 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 9 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 224 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 10 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 226 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 11 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 228 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 12 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 230 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 13 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 27.0 | 232 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 95.0 | 1.0 | 🧕🏾 |
| 14 | 155 | 49 | 2 | queue | treatment_wait_begins | 206.540636 | NaN | 1 | 26.0 | 234 | NaN | 205 | 305.0 | Waiting for Treatment | NaN | 105.0 | 1.0 | 🧕🏾 |
generate_animation(
full_patient_df_plus_pos=full_patient_df_plus_pos.sort_values(['patient', 'minute']),
event_position_df= event_position_df,
scenario=g(),
debug_mode=True,
setup_mode=False,
include_play_button=True,
icon_and_text_size=20,
plotly_height=700,
frame_duration=800,
frame_transition_duration=200,
plotly_width=1200,
override_x_max=300,
override_y_max=500,
time_display_units="dhm",
display_stage_labels=False,
add_background_image="https://raw.githubusercontent.com/Bergam0t/vidigi/refs/heads/main/examples/example_1_simplest_case/Simplest%20Model%20Background%20Image%20-%20Horizontal%20Layout.drawio.png",
)Output animation generation complete at 10:21:52
animate_activity_log(
event_log=my_trial.all_event_logs[my_trial.all_event_logs['run']==1],
event_position_df= event_position_df,
scenario=g(),
debug_mode=True,
setup_mode=False,
every_x_time_units=1,
include_play_button=True,
icon_and_text_size=20,
gap_between_entities=6,
gap_between_rows=25,
plotly_height=700,
frame_duration=200,
plotly_width=1200,
override_x_max=300,
override_y_max=500,
limit_duration=g.sim_duration,
wrap_queues_at=25,
step_snapshot_max=125,
time_display_units="dhm",
display_stage_labels=False,
add_background_image="https://raw.githubusercontent.com/Bergam0t/vidigi/refs/heads/main/examples/example_1_simplest_case/Simplest%20Model%20Background%20Image%20-%20Horizontal%20Layout.drawio.png",
)Animation function called at 10:23:11
Iteration through minute-by-minute logs complete 10:23:13
Snapshot df concatenation complete at 10:23:14
Reshaped animation dataframe finished construction at 10:23:14
Placement dataframe finished construction at 10:23:14
Output animation generation complete at 10:23:16
Total Time Elapsed: 4.24 seconds